package cn.stylefeng.guns.modular.tcpconnection.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.thread.GlobalThreadPool;
import cn.hutool.core.util.ObjectUtil;
import cn.stylefeng.guns.modular.tcpconnection.TcpConnectionHandler;
import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException;
import cn.stylefeng.guns.modular.tcpconnection.entity.DeviceConnect;
import cn.stylefeng.guns.modular.tcpconnection.enums.DeviceConnectExceptionEnum;
import cn.stylefeng.guns.modular.tcpconnection.mapper.DeviceConnectMapper;
import cn.stylefeng.guns.modular.tcpconnection.pojo.request.DeviceConnectRequest;
import cn.stylefeng.guns.modular.tcpconnection.service.DeviceConnectService;
import cn.stylefeng.roses.kernel.db.api.factory.PageFactory;
import cn.stylefeng.roses.kernel.db.api.factory.PageResultFactory;
import cn.stylefeng.roses.kernel.db.api.pojo.page.PageResult;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.List;

/**
 * 业务实现层
 *
 * @author gummybear
 * @date 2023/06/29 19:15
 */
@Service
public class DeviceConnectServiceImpl extends ServiceImpl<DeviceConnectMapper, DeviceConnect> implements DeviceConnectService {

	@Override
    public void add(DeviceConnectRequest deviceConnectRequest) {
        DeviceConnect deviceConnect = new DeviceConnect();
        BeanUtil.copyProperties(deviceConnectRequest, deviceConnect);
        this.save(deviceConnect);
    }

    @Override
    public void del(DeviceConnectRequest deviceConnectRequest) {
        DeviceConnect deviceConnect = this.queryDeviceConnect(deviceConnectRequest);
        this.removeById(deviceConnect.getLinkType());
    }

    @Override
    public void edit(DeviceConnectRequest deviceConnectRequest) {
        DeviceConnect deviceConnect = this.queryDeviceConnect(deviceConnectRequest);
        BeanUtil.copyProperties(deviceConnectRequest, deviceConnect);
        this.updateById(deviceConnect);
    }

    @Override
    public DeviceConnect detail(DeviceConnectRequest deviceConnectRequest) {
        return this.queryDeviceConnect(deviceConnectRequest);
    }

    @Override
    public PageResult<DeviceConnect> findPage(DeviceConnectRequest deviceConnectRequest) {
        LambdaQueryWrapper<DeviceConnect> wrapper = createWrapper(deviceConnectRequest);
        Page<DeviceConnect> sysRolePage = this.page(PageFactory.defaultPage(), wrapper);
        return PageResultFactory.createPageResult(sysRolePage);
    }

    @Override
    public List<DeviceConnect> findList(DeviceConnectRequest deviceConnectRequest) {
        LambdaQueryWrapper<DeviceConnect> wrapper = this.createWrapper(deviceConnectRequest);
        return this.list(wrapper);
    }

    @Override
    @PostConstruct
    public void tcpListenerService() {
        Thread listenerThread = new Thread(() -> {
            try {
                int port = 11451;
                ServerSocket serverSocket = new ServerSocket(port);
                System.out.println("TCP Listener started on port " + port);

                while (true) {
                    Socket clientSocket = serverSocket.accept();

                    GlobalThreadPool.execute(() -> {
                        TcpConnectionHandler connectionHandler = new TcpConnectionHandler(clientSocket, this);
                        connectionHandler.run();

                    });
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        });


        listenerThread.start();
    }

    /**
     * 获取信息
     *
     * @author gummybear
     * @date 2023/06/29 19:15
     */
    private DeviceConnect queryDeviceConnect(DeviceConnectRequest deviceConnectRequest) {
        DeviceConnect deviceConnect = this.getById(deviceConnectRequest.getLinkType());
        if (ObjectUtil.isEmpty(deviceConnect)) {
            throw new ServiceException(DeviceConnectExceptionEnum.DEVICE_CONNECT_NOT_EXISTED);
        }
        return deviceConnect;
    }

    /**
     * 创建查询wrapper
     *
     * @author gummybear
     * @date 2023/06/29 19:15
     */
    private LambdaQueryWrapper<DeviceConnect> createWrapper(DeviceConnectRequest deviceConnectRequest) {
        LambdaQueryWrapper<DeviceConnect> queryWrapper = new LambdaQueryWrapper<>();

        String linkType = deviceConnectRequest.getLinkType();
        String deviceName = deviceConnectRequest.getDeviceName();
        String deviceType = deviceConnectRequest.getDeviceType();
        String deviceIp =  deviceConnectRequest.getDeviceIp();
        String deviceStatus = deviceConnectRequest.getDeviceStatus();

        queryWrapper.like(ObjectUtil.isNotEmpty(linkType), DeviceConnect::getLinkType, linkType);
        queryWrapper.like(ObjectUtil.isNotEmpty(deviceName), DeviceConnect::getDeviceName, deviceName);
        queryWrapper.like(ObjectUtil.isNotEmpty(deviceType), DeviceConnect::getDeviceType, deviceType);
        queryWrapper.eq(ObjectUtil.isNotNull(deviceIp), DeviceConnect::getDeviceIp, deviceIp);
        queryWrapper.like(ObjectUtil.isNotEmpty(deviceStatus), DeviceConnect::getDeviceStatus, deviceStatus);

        return queryWrapper;
    }

}